import com.google.common.base.Joiner;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;

import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * git地址

 https://gitee.com/yujianlong1988/java8andDisruptor.git
 * 收集器
 * @author yujianlong
 * @create 2018-06-16 11:29
 **/
public class StreamTest3 {//复杂场景排序



	@Test
	public void test1(){//指定顺序排序

		/*
		* 有时候我们会遇到复杂的排序，从sql上已经无法按照要求排序
		* 比如一个之字形排序
		* 排序需求:场景比如订单，首先按照下单时间排序，其次按照之字形，一笔投资如果有赎回就要成对出现，部分赎回还要对应新投资订单成对出现
		* 对于这种需求排序，明显是递归排序，嵌套着排，你还不能分页再排，你不知道是不是我第一个要和最后一个成对出现
		* 所以只能查出全部然后再排，对于量大的，这种方式不适用
		*
		*
		* */
//		Map<String,String>

		long start = System.currentTimeMillis();

		List<Map<String, String>> datas = IntStream.rangeClosed(1, 10000).boxed().map(i -> {
			Map<String, String> ma = new HashMap<>();
			ma.put("name", "name" + i);
			ma.put("order", "" + i);
			return ma;
		}).collect(Collectors.toList());

		//按照order【10 9 3 1 2 8 4 6 7 5】 指定排序


		List<Integer> lists = IntStream.rangeClosed(1, 10000).boxed().collect(Collectors.toList());
		Collections.shuffle(lists);

//		System.out.println(lists);

		Map<String, Integer> collect = lists.parallelStream().collect(Collectors.toMap(i -> i.toString(), i -> lists.indexOf(i)));
//		System.out.println(collect);

//		//真正排序
//		List<Map<String, String>> collect1 = datas.parallelStream().sorted((m1, m2) -> {
//			Integer order1 = collect.get(m1.get("order"));
//			Integer order2 = collect.get(m2.get("order"));
//			return Integer.compare(order1, order2);
//		}).collect(Collectors.toList());

		datas.parallelStream().sorted((m1, m2) -> {
			Integer order1 = collect.get(m1.get("order"));
			Integer order2 = collect.get(m2.get("order"));
			return Integer.compare(order1, order2);
		}).skip(100).limit(10).forEach(System.out::println);

		long end = System.currentTimeMillis();


//		collect1.stream().skip(100).limit(10).forEach(System.out::println);
		System.out.println("耗时="+(end-start)+"ms");

	}






}
